<template>
  <el-select v-bind="$attrs" v-model="selected" placeholder="请选择" filterable style="width: 100%">
    <template #header v-if="checkAll">
      <el-checkbox v-model="isCheckAll" :indeterminate="indeterminate" @change="handleCheckAll">全选</el-checkbox>
    </template>
    <el-option
      v-for="item in list"
      :key="item[valueField]"
      :label="item[labelField]"
      :value="valueNumeric ? Number(item[valueField]) : item[valueField]"
    >
      <slot :item="item"></slot>
    </el-option>
  </el-select>
</template>

<script setup>
import { ref, watch } from 'vue'

// 双向绑定
const selected = defineModel('selected', {
  type: [String, Number, Array, Boolean, Object],
  default: ''
})

const props = defineProps({
  // 列表项
  list: {
    type: Array,
    default: () => []
  },
  // 键字段名（显示的字样）
  labelField: {
    type: String,
    default: 'label'
  },
  // 值字段名（实际代表值）
  valueField: {
    type: String,
    default: 'value'
  },
  // 数字化value，使用前提是必须确保所有字典值为数字或者数字型字符串
  valueNumeric: {
    type: Boolean,
    default: false
  },
  // 是否开启全选
  checkAll: {
    type: Boolean,
    default: false
  }
})

const isCheckAll = ref(false)
const indeterminate = ref(false)

watch(
  selected,
  (newVal) => {
    const { checkAll, list } = props
    if (!checkAll) return // 若未开启全选模式，不进行任何处理

    if (newVal?.length === 0) {
      isCheckAll.value = false
      indeterminate.value = false
    } else if (newVal?.length === list.length) {
      isCheckAll.value = true
      indeterminate.value = false
    } else {
      indeterminate.value = true
    }
  },
  { immediate: true }
)

function handleCheckAll(val) {
  indeterminate.value = false
  const { list, valueField } = props
  if (val) {
    selected.value = list.map((item) => item[valueField])
  } else {
    selected.value = []
  }
}
</script>

<style lang="scss" scoped></style>
